package com.eastday.biz.impl;

import java.util.List;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.InputStreamReader;

import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.NodeVisitor;


import com.eastday.biz.ParseHtmlBiz;
import com.eastday.dao.ImportNewsDao;
import com.eastday.model.NewsInfoModel;
import com.eastday.util.BeanFactory;
import com.eastday.util.ParseConfigFactory;

/**
 * 
 * @author dingxs
 *
 */
public class ParseHtmlBizImpl extends CommonService implements ParseHtmlBiz {

	private List<NewsInfoModel> newsInfoModelList;
	private List<String> fetchPageUrlList;
	private String[] urlinfo;
	private String breakpoint = "";
	private boolean breakstatus = false;
	
	public ParseHtmlBizImpl(){
		super();
	}
	
	@Override
	public void parseHtmlToDb(List<String> pagelinkList, String url) {
		// TODO Auto-generated method stub
		boolean writeflag           = false;
		String dirPath              = ParseConfigFactory.sysConfigModel.getTemppath();
		urlinfo                     = ParseConfigFactory.urlConfigModel.getUrlConfigMap().get(url);
		String filePath             = dirPath + "/" + urlinfo[1];
		File file                   = new File(filePath);
		FileInputStream inputStream = null;
		BufferedReader br           = null;
		if(file.exists())
		{
			try
			{
				inputStream = new FileInputStream(file);
				br          = new BufferedReader(new InputStreamReader(inputStream));
				breakpoint  = br.readLine();
			}
			catch(IOException e)
			{
				this.exceptionHandler.writeToLog(e.getMessage());
			}
			finally
			{
				try
				{
					br.close();
					inputStream.close();
				}
				catch(IOException e)
				{
					this.exceptionHandler.writeToLog(e.getMessage());
				}
			}
		}
		for(String pagelink:pagelinkList)
		{
			this.parseHtml(pagelink, url);
			if(writeflag == false && newsInfoModelList.size()!=0)
			{
				File directory = new File(dirPath);
				if(!directory.exists())
				{
					directory.mkdir();
				}
				FileOutputStream outputStream = null;
				BufferedWriter bw             = null;
				try
				{
					outputStream = new FileOutputStream(file);
					bw           = new BufferedWriter(new OutputStreamWriter(outputStream));
					bw.write(newsInfoModelList.get(0).getTopic().trim(),0,newsInfoModelList.get(0).getTopic().trim().length());
				}
				catch(IOException e)
				{
					this.exceptionHandler.writeToLog(e.getMessage());
				}
				catch(Exception e)
				{
					this.exceptionHandler.writeToLog(e.getMessage());
				}
				finally
				{
					try
					{
						bw.flush();
						bw.close();
						outputStream.close();
					}
					catch(IOException e)
					{
						this.exceptionHandler.writeToLog(e.getMessage());
					}
				}
			}
			if(newsInfoModelList.size()!=0)
			{
				this.importNewsToDB(newsInfoModelList);
			}
			if(breakstatus == true)
			{
				break;
			}
			writeflag = true;
		}
	}
	
	private void parseHtml(String url,String source){
		newsInfoModelList = new ArrayList<NewsInfoModel>();
		Parser parser = new Parser();
		try
		{
			parser.setURL(url);
		}
		catch(ParserException e)
		{
			this.exceptionHandler.writeToLog(e.getMessage());
		}
		NodeVisitor nodeVisitor = new NodeVisitor(){
			public void visitTag(Tag tag){
				if(tag.getAttribute("id")!=null && tag.getAttribute("id").equals(ParseConfigFactory.sysConfigModel.getDivid()))
				{
					NodeList divChildren = tag.getChildren();
					for(int i = 0;i<divChildren.size();i++)
					{
						Node nodeInDiv = divChildren.elementAt(i);
						if(nodeInDiv instanceof TagNode)
						{
							if(((TagNode)nodeInDiv).getTagName().toUpperCase().equals("UL"))
							{
								NodeList ulChildren = nodeInDiv.getChildren();
								for(int j = 0;j<ulChildren.size();j++)
								{
									Node nodeInUl = ulChildren.elementAt(j);
									NewsInfoModel newsInfoModel = new NewsInfoModel();
									if(((TagNode)nodeInUl).getTagName().toUpperCase().equals("LI"))
									{
										NodeList liChildren = nodeInUl.getChildren();
										if(urlinfo[0].trim().length() == 0)
										{
											String topic = "";
											if((liChildren.elementAt(1).getFirstChild()) instanceof TagNode)
											{
												topic = liChildren.elementAt(1).getFirstChild().getNextSibling().getText().trim();
											}
											else
											{
												topic = liChildren.elementAt(1).getFirstChild().getText().trim();
											}
											if(!topic.equals(breakpoint))
											{
												String channel = liChildren.elementAt(0).getFirstChild().getText();
												channel        = channel.substring(1,channel.length()-1);
												newsInfoModel.setChannel(channel);
												newsInfoModel.setTopic(topic);
												newsInfoModel.setLink(urlinfo[2]+((TagNode)liChildren.elementAt(1)).getAttribute("href"));
												newsInfoModel.setDatetime(liChildren.elementAt(2).getFirstChild().getText());
											}
											else
											{
												breakstatus = true;
												return;
											}
										}
										else
										{
											String topic = "";
											if(liChildren.elementAt(0).getFirstChild() instanceof TagNode)
											{
												topic = liChildren.elementAt(0).getFirstChild().getNextSibling().getText().trim();
											}
											else
											{
												topic = liChildren.elementAt(0).getFirstChild().getText().trim();
											}
											if(!topic.equals(breakpoint))
											{
												newsInfoModel.setChannel(urlinfo[0]);
												newsInfoModel.setTopic(topic);
												newsInfoModel.setLink(urlinfo[2]+((TagNode)liChildren.elementAt(0)).getAttribute("href"));
												newsInfoModel.setDatetime(liChildren.elementAt(1).getFirstChild().getText());
											}
											else
											{
												breakstatus = true;
												return;
											}
										}
										newsInfoModelList.add(newsInfoModel);
									}
								}
							}
						}
					}
				}
			}
		};
		try 
		{
			parser.visitAllNodesWith(nodeVisitor);
			for(NewsInfoModel newsInfoModel:newsInfoModelList)
			{
				newsInfoModel.setSource(source);
			}
		}
		catch(ParserException e)
		{
			this.exceptionHandler.writeToLog(e.getMessage());
		}
	}

	@Override
	public List<String> parseHtmlPageLink(String url) {
		// TODO Auto-generated method stub
		fetchPageUrlList = new ArrayList<String>();
		int position = url.lastIndexOf("/");
		String suffix = url.substring(position+1);
		Parser parser = new Parser();
		try {
			parser.setURL(url);
		} catch (ParserException e) {
			// TODO Auto-generated catch block
			this.exceptionHandler.writeToLog(e.getMessage());
		}
		NodeVisitor nodeVisitor = new NodeVisitor(){
			public void visitTag(Tag tag){
				if(tag.getAttribute("id")!=null && tag.getAttribute("id").equals("left"))
				{
					NodeList divChildren = tag.getChildren();
					for(int i = 0;i<divChildren.size();i++)
					{
						Node nodeInDiv = divChildren.elementAt(i);
						if(nodeInDiv instanceof TagNode)
						{
							if(((TagNode)nodeInDiv).getTagName().toUpperCase().equals("P"))
							{
								NodeList pChildren = nodeInDiv.getChildren();
								for(int j = 0;j < pChildren.size();j++)
								{
									Node nodeInP = pChildren.elementAt(j);
									if(((TagNode)nodeInP).getTagName().toUpperCase().equals("A"))
									{
											Pattern pattern = Pattern.compile("^\\d*$");
											String pageNo = nodeInP.getFirstChild().getText().trim();
											Matcher matcher = pattern.matcher(pageNo);
											if(matcher.find())
											{
												int position = ((TagNode)nodeInP).getAttribute("href").lastIndexOf("/")+1;
												fetchPageUrlList.add(((TagNode)nodeInP).getAttribute("href").substring(position));
											}
									}
									
								}
							}
						}
					}
				}
			}
		};
		try {
			parser.visitAllNodesWith(nodeVisitor);
		} catch (ParserException e) {
			// TODO Auto-generated catch block
			this.exceptionHandler.writeToLog(e.getMessage());
		}
		for(int i = 0;i<fetchPageUrlList.size();i++)
		{
			String replace = url.replace(suffix, fetchPageUrlList.get(i));
			fetchPageUrlList.set(i, replace);
		}
		return fetchPageUrlList;

	}
	
	private void importNewsToDB(List<NewsInfoModel> newsInfoModelList){
		ImportNewsDao importNewsDao = (ImportNewsDao)BeanFactory.getBean("ImportNewsOracleDao");
		importNewsDao.importNews(newsInfoModelList);
		
	}

}
